package com.taptech.doufu.bean;

import com.taptech.doufu.util.TTLog;
import com.taptech.doufu.bean.cp.CpBean;
import com.taptech.doufu.bean.cartoon.CartoonBean;
import com.taptech.doufu.bean.personalcenter.PersonalCardInfo;
import com.taptech.doufu.bean.personalcenter.TopicBean;
import com.taptech.doufu.util.DiaobaoUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * Company: DiaoBao
 * </p>
 *
 * @author huangzh
 * @date 2014-3-17
 */
public class BaseBean implements Serializable
{

    private static final long serialVersionUID = 1L;

    private DiaobaoJson json;

    static final public int HOME_NOTE_RECOMMEND = 1001;

    private int specialFlag;





    public DiaobaoJson getJson()
    {
        if (json == null || !json.keys().hasNext())
        {
            JSONObject jsonData = new JSONObject();
            Field fields[] = getClass().getDeclaredFields();
            for (Field field : fields)
            {
                try
                {
                    if (field.getName().equalsIgnoreCase("serialVersionUID"))
                        continue;
                    field.setAccessible(true);
                    jsonData.put(field.getName(), String.valueOf(field.get(this)));
                } catch (Exception e)
                {
                    e.printStackTrace();
                }
            }
            json = new DiaobaoJson(jsonData);
        }
        return json;
    }

    private Object convert(Class<?> type, Object json) throws InstantiationException, IllegalAccessException, JSONException
    {
        // Log.v("convert", "convert from: "+json);
        if (String.class.isAssignableFrom(type))
        {
            if (json instanceof String || json instanceof Integer)
            {
                return String.valueOf(json);
            }
            return "";
        }

        if (Integer.class.isAssignableFrom(type))
        {
            if (json instanceof Integer)
            {
                return json;
            }
            return 0;
        }

        if (int.class.isAssignableFrom(type))
        {
            if (json instanceof Integer)
            {
                return json;
            }
            return 0;
        }

        if (Boolean.class.isAssignableFrom(type))
        {
            if (json instanceof Boolean)
            {
                return json;
            }
            return false;
        }
        if (boolean.class.isAssignableFrom(type))
        {
            if (json instanceof Boolean)
            {
                return json;
            }
            return false;
        }

        if (BaseBean.class.isAssignableFrom(type) || MineAbstractBean.class.isAssignableFrom(type))
        {

            BaseBean bean = (BaseBean) type.newInstance();

            if (json instanceof JSONObject)
            {
                bean.setJson2((JSONObject) json);
            }

            return bean;
        }

        if (type.isArray())
        {
            @SuppressWarnings("rawtypes") Class eType = type.getComponentType();

            if (!(json instanceof JSONArray))
            {
                return Array.newInstance(eType, 0);
            }

            JSONArray array = (JSONArray) json;

            Object[] objects = (Object[]) Array.newInstance(eType, array.length());

            for (int i = 0; i < array.length(); ++i)
            {
                objects[i] = convert(eType, array.get(i));
            }

            return objects;
        }

        throw new RuntimeException("unsupport class: " + type.getName());
        //throw new RuntimeException("unsupport class: ");
    }

    public void setJson2(JSONObject json)
    {
        //Log.v("setJson2", "convert to: " + getClass().getSimpleName() + " from: " + json);
        if (json == null)
        {
            // Log.v("setJson2", "skip null json");
            return;
        }
        this.json = new DiaobaoJson(json);

        for (Field field : getClass().getDeclaredFields())
        {
            //打开字段访问权限
            field.setAccessible(true);
            Class<?> type = field.getType();
            String fieldName = field.getName();

            if (fieldName.equals("serialVersionUID"))
            {
                // Log.v("setJson2", "skip serialVersionUID");
                continue;
            }
            if (fieldName.equals("json"))
            {
                // Log.v("setJson2", "skip field json");
                continue;
            }
            if (!json.has(fieldName))
            {
                //Log.v("setJson2", "empty field " + fieldName);
                continue;
            }
            if (!field.getType().isAssignableFrom(String.class))
            {
                try
                {
                    if (json.getString(fieldName) != null && json.getString(fieldName).equals("null"))
                    {
                        continue;
                    }
                } catch (JSONException e)
                {
                    e.printStackTrace();
                }
            }
            /*String string = new String();
            if (!field.getClass().equals(string.getClass())) {
                if (fieldName.equals("null")){
                    continue;
                }
            }*/
            try
            {
                // Log.v("setJson2", "converting field "+fieldName);
                Object obj = convert(type, json.get(fieldName));
                field.set(this, obj);
                //Log.v("setJson2", "converted field " + fieldName + " to: " + obj + " from: " + json.get(fieldName));
            } catch (InstantiationException e)
            {
                e.printStackTrace();
            } catch (IllegalAccessException e)
            {
                e.printStackTrace();
            } catch (JSONException e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * @param json
     * @deprecated use setJson2 instead
     */
    public void setJson(JSONObject json)
    {
        Field fields[] = new Field[0];
        String fieldName;
        Object value = null;
        try
        {
            if (json == null)
                return;
            TTLog.s(json.toString(0));
            this.json = new DiaobaoJson(json);
            fields = getClass().getDeclaredFields();


        } catch (Exception e)
        {
            e.printStackTrace();
        }
        for (Field field : fields)
        {
            field.setAccessible(true);
            fieldName = field.getName();
            if (fieldName.equals("json"))
                continue;
            if (fieldName.equalsIgnoreCase("serialVersionUID"))
                continue;

            if (json.has(fieldName) && !json.isNull(fieldName))
            {
                try
                {
                    if (fieldName.equalsIgnoreCase("comuBrief"))
                    {
                        JSONObject comObj = json.getJSONObject(fieldName);
                        GroupBriefBean group = new GroupBriefBean();
                        group.setJson(comObj);
                        value = group;
                    } else if (fieldName.equalsIgnoreCase("community"))
                    {
                        JSONObject userObj = json.getJSONObject(fieldName);
                        GroupInfoBean community = new GroupInfoBean();
                        community.setJson(userObj);
                        value = community;
                    } else if (fieldName.equalsIgnoreCase("user"))
                    {
                        JSONObject userObj = json.getJSONObject(fieldName);
                        UserBean user = new UserBean();
                        user.setJson(userObj);
                        value = user;
                    } else if (fieldName.equalsIgnoreCase("sweep"))
                    {
                        JSONObject sweepObj = json.getJSONObject(fieldName);
                        SweepBean sweep = new SweepBean();
                        sweep.setJson(sweepObj);
                        value = sweep;
                    } else if (fieldName.equalsIgnoreCase("novel"))
                    {
                        JSONObject novelObj = json.getJSONObject(fieldName);
                        NovelBean novel = new NovelBean();
                        novel.setJson(novelObj);
                        value = novel;
                    } else if (fieldName.equalsIgnoreCase("to_user"))
                    {
                        JSONObject userObj = json.getJSONObject(fieldName);
                        UserBean user = new UserBean();
                        user.setJson(userObj);
                        value = user;
                    } else if (fieldName.equalsIgnoreCase("friend"))
                    {
                        JSONObject userObj = json.getJSONObject(fieldName);
                        UserBean user = new UserBean();
                        user.setJson(userObj);
                        value = user;
                    } else if (fieldName.equalsIgnoreCase("actionMsg"))
                    {
                        JSONObject actionObj = json.getJSONObject(fieldName);
                        ActionMsgBean action = new ActionMsgBean();
                        action.setJson(actionObj);
                        value = action;
                    } else if (fieldName.equalsIgnoreCase("images"))
                    {
                        JSONArray jsonImages = json.getJSONArray(fieldName);
                        value = initImages(jsonImages);
                    } else if (fieldName.equalsIgnoreCase("comments"))
                    {
                        JSONArray jsonComments = json.getJSONArray(fieldName);
                        value = initComments(jsonComments);
                    } else if (fieldName.equalsIgnoreCase("result"))
                    {
                        JSONArray jsonResule = json.getJSONArray(fieldName);
                        value = initResult(jsonResule);
                    } else if (fieldName.equalsIgnoreCase("replies"))
                    {
                        JSONArray jsonResule = json.getJSONArray(fieldName);
                        value = initReplies(jsonResule);
                    } else if (fieldName.equalsIgnoreCase("tags"))
                    {
                        JSONArray jsonTags = json.getJSONArray(fieldName);
                        value = initTags(jsonTags);
                    } else if (fieldName.equalsIgnoreCase("praisers"))
                    {
                        JSONArray jsonPraise = json.getJSONArray(fieldName);
                        value = initPraise(jsonPraise);
                    } else if (fieldName.equalsIgnoreCase("routes"))
                    {
                        JSONArray jsonResule = json.getJSONArray(fieldName);
                        value = initRoutes(jsonResule);
                    } else if (fieldName.equalsIgnoreCase("novel_list") || fieldName.equalsIgnoreCase("novels") || fieldName.equalsIgnoreCase("carousels") || fieldName.equalsIgnoreCase("videos") || fieldName.equalsIgnoreCase("topics"))
                    {
                        JSONArray jsonNovels = json.getJSONArray(fieldName);
                        value = initNovels(jsonNovels);

                    } else if (fieldName.equalsIgnoreCase("entries"))
                    {
                        JSONObject jsonObject = json.getJSONObject(fieldName);
                        HomeImageEntriesBean entriesBean = new HomeImageEntriesBean();
                        entriesBean.setJson(jsonObject);
                        value = entriesBean;
                    } else if (fieldName.equalsIgnoreCase("cartoon_entry") || fieldName.equalsIgnoreCase("drawing_entry") || fieldName.equalsIgnoreCase("market_entry") || fieldName.equalsIgnoreCase("novel_entry") || fieldName.equalsIgnoreCase("novel_review_entry") || fieldName.equalsIgnoreCase("square_entry"))
                    {
                        JSONObject jsonObject = json.getJSONObject(fieldName);
                        HomeSingleImageBean singleImageBean = new HomeSingleImageBean();
                        singleImageBean.setJson(jsonObject);
                        value = singleImageBean;
                    } else if (fieldName.equalsIgnoreCase("comics_list"))
                    {
                        JSONArray jsonCartons = json.getJSONArray(fieldName);
                        value = initCartons(jsonCartons);

                    } else if (fieldName.equalsIgnoreCase("cps"))
                    {
                        JSONArray jsonNovels = json.getJSONArray(fieldName);
                        value = initCps(jsonNovels);
                    } else if (fieldName.equalsIgnoreCase("novel_reviews"))
                    {
                        JSONArray jsonNovels = json.getJSONArray(fieldName);
                        value = initSweep(jsonNovels);
                    } else if (fieldName.equalsIgnoreCase("novel"))
                    {
                        JSONObject novelObj = json.getJSONObject(fieldName);
                        NovelBean novel = new NovelBean();
                        novel.setJson(novelObj);
                        value = novel;
                    } else if (fieldName.equalsIgnoreCase("top_albums") || fieldName.equalsIgnoreCase("tag_big") || fieldName.equalsIgnoreCase("drawing_big") || fieldName.equalsIgnoreCase("novel_big") || fieldName.equalsIgnoreCase("common_albums") || fieldName.equalsIgnoreCase("part1_albums") || fieldName.equalsIgnoreCase("part2_albums") || fieldName.equalsIgnoreCase("part3_albums") || fieldName.equalsIgnoreCase("part4_albums") || fieldName.equalsIgnoreCase("part5_albums") || fieldName.equalsIgnoreCase("novel_activity_albums"))
                    {
                        JSONArray albumslObj = json.getJSONArray(fieldName);
                        value = initAlbums(albumslObj);
                    } else if (fieldName.equalsIgnoreCase("owner"))
                    {
                        JSONObject ownerObj = json.getJSONObject(fieldName);
                        OwnerBean owner = new OwnerBean();
                        owner.setJson(ownerObj);
                        value = owner;
                    } else if (fieldName.equalsIgnoreCase("article"))
                    {
                        JSONObject ownerObj = json.getJSONObject(fieldName);
                        ArticleBean article = new ArticleBean();
                        article.setJson(ownerObj);
                        value = article;
                    } else if (fieldName.equalsIgnoreCase("extra"))
                    {
                        JSONObject extraObj = json.getJSONObject(fieldName);
                        ExtraBean extraBean = new ExtraBean();
                        extraBean.setJson(extraObj);
                        value = extraBean;
                    } else if (fieldName.equalsIgnoreCase("signed_author_album") || fieldName.equalsIgnoreCase("signed_author_novel_album") || fieldName.equalsIgnoreCase("finished_novel_entry"))
                    {
                        JSONObject userObj = json.getJSONObject(fieldName);
                        AlbumsBean albumsBean = new AlbumsBean();
                        albumsBean.setJson(userObj);
                        value = albumsBean;
                    } else if (fieldName.equalsIgnoreCase("spend_num"))
                    {
                        value = json.getString("spend_num");
                    } else if (fieldName.equalsIgnoreCase("images"))
                    {
                        JSONArray imagebeans = json.getJSONArray(fieldName);
                        value = DiaobaoUtil.json2list(ImageBean.class, imagebeans);
                    } else if (fieldName.equalsIgnoreCase("is_vip")) {
                        value = json.getInt(fieldName);
                    } else if (fieldName.equalsIgnoreCase("is_year_vip")) {
                        value = json.getInt(fieldName);
                    } else if (fieldName.equalsIgnoreCase("level")) {
                        value = json.getInt(fieldName);
                    } else {
                        if (json.get(fieldName) instanceof String) {
                            value = json.getString(fieldName);
                        } else if (json.get(fieldName) instanceof Integer) {
                            value = json.getString(fieldName);
                        } else if (json.get(fieldName) instanceof Boolean) {
                            value = json.getBoolean(fieldName);
                        } else {
                            value = null;
                        }
                    }
                    // TTLog.s(fieldName+":::"+value);
                    field.set(this, value);
                } catch (Exception e)
                {

                }

            }
        }
    }

    private Object initCartons(JSONArray jsonCartons)
    {
        List<CartoonBean> result = new ArrayList<CartoonBean>();
        CartoonBean cartoonBean;
        for (int i = 0; i < jsonCartons.length(); i++)
        {
            cartoonBean = new CartoonBean();
            try
            {
                cartoonBean.setJson(jsonCartons.getJSONObject(i));
            } catch (JSONException e)
            {
                e.printStackTrace();
            }
            result.add(cartoonBean);
        }
        return result;
    }

    private TopicBean[] initTopics(JSONArray jsontopics)
    {
        TopicBean[] topics = new TopicBean[jsontopics.length()];
        for (int i = 0; i < jsontopics.length(); i++)
        {
            topics[i] = new TopicBean();
            try
            {
                topics[i].setJson(jsontopics.getJSONObject(i));
            } catch (JSONException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        return topics;
    }

    public PersonalCardInfo[] initPraise(JSONArray jsonPraise) throws JSONException
    {
        PersonalCardInfo[] tags = new PersonalCardInfo[jsonPraise.length()];
        for (int i = 0; i < jsonPraise.length(); i++)
        {
            tags[i] = new PersonalCardInfo();
            tags[i].setJson(jsonPraise.getJSONObject(i));
        }
        return tags;
    }

    public ImageBean[] initImages(JSONArray jsonImages) throws JSONException
    {
        ImageBean[] imgs = new ImageBean[jsonImages.length()];
        for (int i = 0; i < jsonImages.length(); i++)
        {
            imgs[i] = new ImageBean();
            imgs[i].setJson2(jsonImages.getJSONObject(i));
        }

        return imgs;
    }

    public CommentDataBean[] initComments(JSONArray jsonComments) throws JSONException
    {
        CommentDataBean[] imgs = new CommentDataBean[jsonComments.length()];
        for (int i = 0; i < jsonComments.length(); i++)
        {
            imgs[i] = new CommentDataBean();
            imgs[i].setJson(jsonComments.getJSONObject(i));
        }

        return imgs;
    }

    public TagsBean[] initTags(JSONArray jsonImages) throws JSONException
    {
        TagsBean[] tags = new TagsBean[jsonImages.length()];
        for (int i = 0; i < jsonImages.length(); i++)
        {
            tags[i] = new TagsBean();
            tags[i].setJson(jsonImages.getJSONObject(i));
        }

        return tags;
    }

    public List<RoutesBean> initRoutes(JSONArray jsonResule) throws JSONException
    {
        List<RoutesBean> result = new ArrayList<RoutesBean>();
        RoutesBean routesBean;
        for (int i = 0; i < jsonResule.length(); i++)
        {
            routesBean = new RoutesBean();
            routesBean.setJson(jsonResule.getJSONObject(i));
            result.add(routesBean);
        }
        return result;
    }

    public List<GroupInfoBean> initResult(JSONArray jsonResule) throws JSONException
    {
        List<GroupInfoBean> result = new ArrayList<GroupInfoBean>();
        GroupInfoBean resultBean;
        for (int i = 0; i < jsonResule.length(); i++)
        {
            resultBean = new GroupInfoBean();
            resultBean.setJson(jsonResule.getJSONObject(i));
            result.add(resultBean);
        }

        return result;
    }

    public List<ReplyDataBean> initReplies(JSONArray jsonResule) throws JSONException
    {
        List<ReplyDataBean> result = new ArrayList<ReplyDataBean>();
        ReplyDataBean resultBean;
        for (int i = 0; i < jsonResule.length(); i++)
        {
            resultBean = new ReplyDataBean();
            resultBean.setJson(jsonResule.getJSONObject(i));
            result.add(resultBean);
        }
        return result;
    }

    public List<HomeTopBean> initNovels(JSONArray jsonNovels) throws JSONException
    {

        List<HomeTopBean> result = new ArrayList<HomeTopBean>();
        HomeTopBean resultBean;
        for (int i = 0; i < jsonNovels.length(); i++)
        {
            resultBean = new HomeTopBean();
            resultBean.setJson(jsonNovels.getJSONObject(i));
            result.add(resultBean);
        }
        return result;
    }

    public List<CpBean> initCps(JSONArray jsonNovels) throws JSONException
    {

        List<CpBean> result = new ArrayList<CpBean>();
        CpBean resultBean;
        for (int i = 0; i < jsonNovels.length(); i++)
        {
            resultBean = new CpBean();
            resultBean.setJson(jsonNovels.getJSONObject(i));
            result.add(resultBean);
        }
        return result;
    }

    public List<SweepBean> initSweep(JSONArray jsonNovels) throws JSONException
    {

        List<SweepBean> result = new ArrayList<SweepBean>();
        SweepBean resultBean;
        for (int i = 0; i < jsonNovels.length(); i++)
        {
            resultBean = new SweepBean();
            resultBean.setJson(jsonNovels.getJSONObject(i));
            result.add(resultBean);
        }
        return result;
    }

    public List<AlbumsBean> initAlbums(JSONArray jsonAlbums) throws JSONException
    {
        List<AlbumsBean> result = new ArrayList<AlbumsBean>();
        AlbumsBean resultBean;
        for (int i = 0; i < jsonAlbums.length(); i++)
        {
            resultBean = new AlbumsBean();
            resultBean.setJson(jsonAlbums.getJSONObject(i));
            result.add(resultBean);
        }
        return result;
    }

    public JSONObject toJson()
    {
        JSONObject jsonObj = new JSONObject();
        try
        {
            Field fields[] = getClass().getDeclaredFields();
            String fieldName;
            for (Field field : fields)
            {
                fieldName = field.getName();
                jsonObj.put(fieldName, field.get(this));
            }
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return jsonObj;
    }


    public int getSpecialFlag()
    {
        return specialFlag;
    }

    public void setSpecialFlag(int specialFlag)
    {
        this.specialFlag = specialFlag;
    }
}
